#!/usr/bin/env python
#-*- coding: UTF-8 -*-
# taskserver.py: task manager server
#
# Copyright (C) 2008-2010 Hily Jiang <hilyjiang@gmail.com>
#
# This file is part of dtask.
#
# This software is provided 'as-is', without any express or implied
# warranty.  In no event will the authors be held liable for any damages
# arising from the use of this software.
#
# Permission is granted to anyone to use this software for any purpose,
# including commercial applications, and to alter it and redistribute it
# freely, subject to the following restrictions:
#
# 1. The origin of this software must not be misrepresented; you must not
#    claim that you wrote the original software. If you use this software
#    in a product, an acknowledgment in the product documentation would be
#    appreciated but is not required.
# 2. Altered source versions must be plainly marked as such, and must not be
#    misrepresented as being the original software.
# 3. This notice may not be removed or altered from any source distribution.

"""
Task Manager Server.

It include two interfaces.
One for Application, another for Scheduler.
"""

import threading
import socket
from time import sleep

from task.manager import TaskManager
from task.appif import *
from task.schif import *


CFG_APP_IP = ''
CFG_APP_PORT = 7708
CFG_SCH_IP = '127.0.0.1'
CFG_SCH_PORT = 7709

CFG_TASK_SQLITEDB = ':memory:'
# interval to check if task is timeout
CFG_TASK_TIMEOUT_INTERVAL = 30
# interval to reset tasks
# (scheduling, scheduled, processing, processed, transfering)
CFG_TASK_RESET_INTERVAL = (10, 20, 40, 50, 60)
# interval to clear tasks
# (finished, returned, failed)
CFG_TASK_CLEAR_INTERVAL = (600, 600, 600)


def main():
    try:
        appServerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        appServerSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        appServerSock.bind((CFG_APP_IP, CFG_APP_PORT))
        appServerSock.listen(0)
        print 'Application interface listen on: %s:%s' % (CFG_APP_IP, CFG_APP_PORT)

        schServerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        schServerSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        schServerSock.bind((CFG_SCH_IP, CFG_SCH_PORT))
        schServerSock.listen(0)
        print 'Scheduler interface listen on: %s:%s' % (CFG_SCH_IP, CFG_SCH_PORT)
    except Exception, e:
        print e

    appClientSocks = []
    schClientSocks = []

    taskManager = TaskManager(CFG_TASK_SQLITEDB, CFG_TASK_TIMEOUT_INTERVAL,
                              CFG_TASK_RESET_INTERVAL, CFG_TASK_CLEAR_INTERVAL)

    appThread = threading.Thread(target=startApplicationIf,
                   args=(taskManager, appServerSock, appClientSocks))
    schThread = threading.Thread(target=startSchedulerIf,
                   args=(taskManager, schServerSock, schClientSocks))
    appThread.setDaemon(True)
    schThread.setDaemon(True)
    appThread.start()
    schThread.start()

    try:
        while True: sleep(100)
    except KeyboardInterrupt:
        print 'Application interface quit by KeyboardInterrupt'
        appServerSock.close()
        for sock in appClientSocks:
            sock.close()
        print 'Scheduler interface quit by KeyboardInterrupt'
        schServerSock.close()
        for sock in schClientSocks:
            sock.close()


if __name__ == '__main__':
    main()
